﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;

namespace GluePathModule
{
    [XmlInclude(typeof(GluePathItemCircle))]
    public class GluePathItemCircle : GluePathItemBase
    {
        [Description("圆心设定"), Category("整圆设定")]
        public PointData Center
        {
            get;
            set;
        }
        [Description("圆的起点设定"), Category("整圆设定")]
        public PointData Start
        {
            get;
            set;
        }
        [Description("圆心设定"), Category("整圆转换")]
        public PointData CenterTransfer
        {
            get;
            set;
        }
        [Description("圆的起点设定"), Category("整圆转换")]
        public PointData StartTransfer
        {
            get;
            set;
        }
        [Description("圆的半径设定"), Category("整圆设定")]
        public double R
        {
            get;
            set;
        }
        [Description("圆的半径设定"), Category("整圆设定")]
        public double RTransfer
        {
            get;
            set;
        }
        [Description("圆的半径设定"), Category("整圆设定")]
        public double 圆的角度
        {
            get;
            set;
        }
        [Browsable(false)]
        public bool bUseZheight
        {
            get;
            set;
        }
        [Browsable(false)]
        public string UseZheightName
        {
            get;
            set;
        }
        [Browsable(false)]
        public int iDrawStep
        {
            get;
            set;
        }
        public GluePathItemCircle()
        {
            iDrawStep = 0;
            Name = "";
            Remark = "";
            圆的角度 = 360;
            UseZheightName = "";
            Center = new PointData();
            Start = new PointData();

        }

        public override void DrawItem(DrawerControl drawer, DrawMode drawMode = DrawMode.UnitIsSelected)
        {
            base.DrawItem(drawer);
            if (drawMode == DrawMode.Background)
            {
                drawer.DrawCircle(new System.Drawing.Pen(System.Drawing.Color.Gray, 1), Center.X, Center.Y, R);
                return;
            }
            else if (drawMode == DrawMode.UnitIsNotSelect)
            {
                drawer.DrawCircle(new System.Drawing.Pen(System.Drawing.Color.White, 3), Center.X, Center.Y, R);
                return;
            }
            if (空动作路径)
            {
                drawer.DrawCircle(new System.Drawing.Pen(System.Drawing.Color.Blue, 3), Center.X, Center.Y, R);
            }
            else
            {
                drawer.DrawCircle(new System.Drawing.Pen(System.Drawing.Color.Green, 3), Center.X, Center.Y, R);
            }
            if (Select)
            {
                drawer.DrawPoint(new System.Drawing.Pen(System.Drawing.Color.Red, 2), Center.X, Center.Y, 0.5);
                drawer.DrawPoint(new System.Drawing.Pen(System.Drawing.Color.Red, 2),Start.X, Start.Y, 0.5);
            }


        }




        public override bool IsOnSelect(double dPosX, double dPosY, double dJudageDis)
        {
           
            double dDistance = Math.Abs((GetDisFrom2Points(dPosX, dPosY, Center.X, Center.Y) - R));

            if (dDistance < dJudageDis)
            {
                Select = true;
                return Select;
            }
            else
            {
                return Select;
            }

        }
        public double GetDisFrom2Points(double x1, double y1, double x2, double y2)
        {
            return Math.Sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
        }
        public override bool GetLastPoint(out double dPosX, out double dPosY, out double dPosZ, out double dPosU)
        {
            dPosX = Start.X;
            dPosY = Start.Y;
            dPosZ = Start.Z;
            dPosU = Start.U;
            return true;
        }
        public override bool GetFirstPoint(out double dPosX, out double dPosY, out double dPosZ, out double dPosU)
        {
            dPosX = Start.X;
            dPosY = Start.Y;
            dPosZ = Start.Z;
            dPosU = Start.U;
            return true;
        }
       
        public override GluePathItemBase CopyItem()
        {
            GluePathItemCircle itemNew = (GluePathItemCircle)MemberwiseClone();
            itemNew.Center = new PointData(Center);
            itemNew.Start= new PointData(Center);
            itemNew.CenterTransfer = new PointData(CenterTransfer);
            itemNew.StartTransfer = new PointData(StartTransfer);
            return itemNew;
        }
        override public GluePathItemBase Paste()
        {
            //CenterX = CenterX + 1;
            //CenterY = CenterY + 1;
            //StartX = StartX + 1;
            //StartY = StartY + 1;

            return CopyItem();
        }
        public override void OffSetItem(double dOffSetX, double dOffSetY)
        {
            Center.X = Center.X + dOffSetX;
            Center.Y = Center.Y + dOffSetY;
            Start.X = Start.X + dOffSetX;
            Start.Y = Start.Y + dOffSetY;
        }
        override public void PathUnitMouseDown(double dMouseX, double dMouseY, double dScandle)
        {
            if (Select == false)
                return;
            if (iAdjustStep == 0)
            {
                if (dMouseX > (Center.X - (5 / dScandle)) && dMouseX < (Center.X + (5 / dScandle)) && dMouseY > (Center.Y - (5 / dScandle)) && dMouseY < (Center.Y + (5 / dScandle)))
                {
                    iAdjustStep = 1;
                }
                else
                {
                    //double dDistance = Math.Abs((GetDisFrom2Points(dMouseX, dMouseY, Center.X, Center.Y) - R));

                    //if (dDistance < (5 / dScandle))
                    //{
                    //    iAdjustStep = 2;
                    //}
                    //else
                    //{

                    //}
                    if (dMouseX > (Start.X - (5 / dScandle)) && dMouseX < (Start.X + (5 / dScandle)) && dMouseY > (Start.Y - (5 / dScandle)) && dMouseY < (Start.Y + (5 / dScandle)))
                    {
                        iAdjustStep = 2;
                    }
                }

            }
        }
        override public void PathUnitMouseMove(double dMouseX, double dMouseY)
        {
            if (Select == false)
                return;
            if (iAdjustStep == 1)
            {
                double dDiffientX = Start.X - Center.X;
                double dDiffientY = Start.Y - Center.Y;

                Center.X = dMouseX;
                Center.Y = dMouseY;

                Start.X = dDiffientX + Center.X;
                Start.Y = dDiffientY + Center.Y;

            }
            if (iAdjustStep == 2)
            {
                Start.X = dMouseX;
                Start.Y = dMouseY;
                R = Math.Sqrt((Start.X - Center.X) * (Start.X - Center.X) + (Start.Y - Center.Y) * (Start.Y - Center.Y));

            }
        }
        override public void PathUnitMouseUp(double dMouseX, double dMouseY)
        {
            if (Select == false)
                return;
            if (iAdjustStep == 1)
            {
                double dDiffientX = Start.X - Center.X;
                double dDiffientY = Start.Y - Center.Y;

                Center.X = dMouseX;
                Center.Y = dMouseY;

                Start.X = dDiffientX + Center.X;
                Start.Y = dDiffientY + Center.Y;
                iAdjustStep = 0;


            }
            if (iAdjustStep == 2)
            {
                Start.X = dMouseX;
                Start.Y = dMouseY;
                R = Math.Sqrt((Start.X - Center.X) * (Start.X - Center.X) + (Start.Y - Center.Y) * (Start.Y - Center.Y));
                iAdjustStep = 0;

            }
        }
        override public void ChangedValue(string strPropertyLabel, Object oldValue)
        {
            
        }
 

       

        public override void OffSetPos(double dOffSetX, double dOffSetY, double dOffSetZ)
        {
            Center.X = Center.X + dOffSetX;
            Center.Y = Center.Y + dOffSetY;
            Center.Z = Center.Z + dOffSetZ;

            Start.X = Start.X + dOffSetX;
            Start.Y = Start.Y + dOffSetY;
            Start.Z = Start.Z + dOffSetZ;

        }
        public override void SetZPos(double dSetPosZ)
        {

            Center.Z = dSetPosZ;

            Start.Z = dSetPosZ;


        }
        public override void SetUPos(double dSetPosU)
        {

            Center.U = dSetPosU;

            Start.U = dSetPosU;


        }
        public override void UpdateZheight(double dZHeight)
        {
            
                Start.Z = dZHeight;
                Center.Z = dZHeight;
            
        }
        public override void GetItemMinMaxXY(out double dMinX, out double dMinY, out double dMaxX, out double dMaxY)
        {
            base.GetItemMinMaxXY(out dMinX, out dMinY, out dMaxX, out dMaxY);

            dMinX = Center.X - R;
            dMinY = Center.Y - R;
            dMaxX = Center.X + R;
            dMaxY = Center.Y + R;
        }

        public override void UpdateEndPos(double dNewEndX, double dNewEndY)
        {
            Start.X = dNewEndX;
            Start.Y = dNewEndY;
        }
        public override void UpdateStartPos(double dNewStartX, double dNewStartY)
        {
            Start.X = dNewStartX;
            Start.Y = dNewStartY;
        }
        public override void PushItem(List<MotionItemBase> motionItems, GluePathGroup gluePathGroup, GluePathUnit gluePathUnit, int indexId,double dOffsetZ)
        {
            

            SpdData spdXYGlue = new SpdData();
            SpdData spdXYH = new SpdData();
            SpdData spdZH = new SpdData();


            double dFirstPosX, dFirstPosY, dFirstPosZ, dFirstPosU;
            GetFirstPoint(out dFirstPosX, out dFirstPosY, out dFirstPosZ, out dFirstPosU);

            #region 判断胶路类型
            bool bIsFirstItem = false;
            bool bisFinalItem = false;
            bool bContinueWithBeforeItem = false;
            bool bContinueWithAferItem = false;
            bool bIsContinueWithAferAndAfterIsOnGlue = false;
            if (indexId == 0)
            {
                bIsFirstItem = true;
            }
            if (indexId == (gluePathUnit.listContinueItems.Count - 1))
            {
                bisFinalItem = true;
            }
            if (indexId == 0)
            {

            }
            else
            {
                double dBeforeItemPosX, dBeforeItemPosY, dBeforeItemPosZ, dBeforeItemPosU;
                gluePathUnit.listContinueItems[indexId - 1].GetLastPoint(out dBeforeItemPosX, out dBeforeItemPosY,
                    out dBeforeItemPosZ, out dBeforeItemPosU);
                if (Math.Abs(dBeforeItemPosX - dFirstPosX) < 0.5 && Math.Abs(dBeforeItemPosY - dFirstPosY) < 0.5 && Math.Abs(dBeforeItemPosZ - dFirstPosZ) < 0.5)
                {
                    bContinueWithBeforeItem = true;
                }
            }
            if (indexId == (gluePathUnit.listContinueItems.Count - 1))
            {
                bContinueWithAferItem = false;
            }
            else
            {
                double dNextItemPosX, dNextItemPosY, dNextItemPosZ, dNextItemPosU;
                double dCurrentEndPosX, dCurrentEndPosY, dCurrentEndPosZ, dCurrentEndPosU;
                GetLastPoint(out dCurrentEndPosX, out dCurrentEndPosY, out dCurrentEndPosZ, out dCurrentEndPosU);
                gluePathUnit.listContinueItems[indexId + 1].GetFirstPoint(out dNextItemPosX, out dNextItemPosY,
                    out dNextItemPosZ, out dNextItemPosU);
                if (Math.Abs(dCurrentEndPosX - dNextItemPosX) < 0.5 && Math.Abs(dCurrentEndPosY - dNextItemPosY) < 0.5 && Math.Abs(dCurrentEndPosZ - dNextItemPosZ) < 0.5)
                {
                    bContinueWithAferItem = true;
                    if (gluePathUnit.listContinueItems[indexId + 1].空动作路径 == false && gluePathUnit.listContinueItems[indexId + 1].Disable == false)
                    {
                        bIsContinueWithAferAndAfterIsOnGlue = true;
                    }
                }
            }
            #endregion

            TranferPosToCur(gluePathUnit, bContinueWithBeforeItem, motionItems,dOffsetZ);
            #region 速度设定

            if (使用单独涂胶速度)
            {
                spdXYGlue.dMoveSpd = 单独涂胶速度;
            }
            else
            {
                if (空动作路径)
                {
                    spdXYGlue.dMoveSpd = gluePathUnit.全局XY高速速度;
                }
                else
                {
                    spdXYGlue.dMoveSpd = gluePathUnit.全局涂胶速度;
                }
            }
            spdXYH.dStartSpd = gluePathUnit.全局开始速度;
            spdXYH.dMoveSpd = gluePathUnit.全局XY高速速度;
            spdXYH.dEndSpd = gluePathUnit.全局结束速度;
            spdXYH.dAcc = gluePathUnit.全局加速度;
            spdXYH.dDec = gluePathUnit.全局减速度;
            spdZH.dStartSpd = gluePathUnit.全局开始速度;
            spdZH.dMoveSpd = gluePathUnit.全局Z高速速度;
            spdZH.dEndSpd = gluePathUnit.全局结束速度;
            spdZH.dAcc = gluePathUnit.全局加速度;
            spdZH.dDec = gluePathUnit.全局减速度;
            if (bIsFirstItem && bisFinalItem)//只有一个点
            {
                spdXYGlue.dStartSpd = gluePathUnit.全局开始速度;
                spdXYGlue.dEndSpd = gluePathUnit.全局结束速度;
                spdXYGlue.dAcc = gluePathUnit.全局加速度;
                spdXYGlue.dDec = gluePathUnit.全局减速度;
            }
            if (bIsFirstItem && (!bContinueWithBeforeItem) && (bContinueWithAferItem) && (!bisFinalItem))//流程的第一个点和后面有连接
            {

                spdXYGlue.dStartSpd = gluePathUnit.全局开始速度;
                spdXYGlue.dEndSpd = spdXYGlue.dMoveSpd;
                spdXYGlue.dAcc = gluePathUnit.全局加速度;
                spdXYGlue.dDec = gluePathUnit.全局减速度;

            }
            if (!bIsFirstItem && (!bContinueWithBeforeItem) && (bContinueWithAferItem) && (!bisFinalItem))//流程中间点，没有和前面的连接，与后面的连接
            {

                spdXYGlue.dStartSpd = gluePathUnit.全局开始速度;
                spdXYGlue.dEndSpd = spdXYGlue.dMoveSpd;
                spdXYGlue.dAcc = gluePathUnit.全局加速度;
                spdXYGlue.dDec = gluePathUnit.全局减速度;

            }
            if (!bIsFirstItem && (bContinueWithBeforeItem) && (bContinueWithAferItem) && (!bisFinalItem))//流程中间点，和前面的连接，与后面的连接
            {

                spdXYGlue.dStartSpd = spdXYGlue.dMoveSpd;
                spdXYGlue.dEndSpd = spdXYGlue.dMoveSpd;
                spdXYGlue.dAcc = gluePathUnit.全局加速度;
                spdXYGlue.dDec = gluePathUnit.全局减速度;
            }
            if (!bIsFirstItem && (bContinueWithBeforeItem) && (!bContinueWithAferItem) && (!bisFinalItem))//流程中间点，和前面的连接，没有与后面的连接
            {
                spdXYGlue.dStartSpd = spdXYGlue.dMoveSpd;
                spdXYGlue.dEndSpd = gluePathUnit.全局结束速度;
                spdXYGlue.dAcc = gluePathUnit.全局加速度;
                spdXYGlue.dDec = gluePathUnit.全局减速度;

            }
            if (!bIsFirstItem && (!bContinueWithBeforeItem) && (!bContinueWithAferItem) && (!bisFinalItem))//流程中间点，没有和前面的连接，没有与后面的连接
            {
                spdXYGlue.dStartSpd = gluePathUnit.全局开始速度;
                spdXYGlue.dEndSpd = gluePathUnit.全局结束速度;
                spdXYGlue.dAcc = gluePathUnit.全局加速度;
                spdXYGlue.dDec = gluePathUnit.全局减速度;
            }
            if (!bIsFirstItem && (bContinueWithBeforeItem) && (!bContinueWithAferItem) && (bisFinalItem))//流程最后一个线段，和前面连接
            {
                spdXYGlue.dStartSpd = spdXYGlue.dMoveSpd;
                spdXYGlue.dEndSpd = gluePathUnit.全局结束速度;
                spdXYGlue.dAcc = gluePathUnit.全局加速度;
                spdXYGlue.dDec = gluePathUnit.全局减速度;
            }
            if (!bIsFirstItem && (!bContinueWithBeforeItem) && (!bContinueWithAferItem) && (bisFinalItem))//流程最后一个线段，没有和前面连接
            {
                spdXYGlue.dStartSpd = gluePathUnit.全局开始速度;
                spdXYGlue.dEndSpd = gluePathUnit.全局结束速度;
                spdXYGlue.dAcc = gluePathUnit.全局加速度;
                spdXYGlue.dDec = gluePathUnit.全局减速度;
            }
            #endregion
            spdXYGlue.dMoveSpd = spdXYGlue.dMoveSpd * RTransfer / R;
            spdXYGlue.dStartSpd = spdXYGlue.dStartSpd * RTransfer / R;
            spdXYGlue.dEndSpd = spdXYGlue.dEndSpd  *RTransfer / R;

            
            
            #region 轨迹设定


            if (bContinueWithBeforeItem == false)
            {
                MotionItemLine motionItemLineUp = new MotionItemLine(spdXYH, StartTransfer);
                motionItemLineUp.Point.Z = gluePathUnit.全局安全高度Z;
                motionItemLineUp.dEndU= StartTransfer.U;
                motionItems.Add(motionItemLineUp);
                MotionItemLine motionItemLineStart = new MotionItemLine(spdZH, StartTransfer);
                motionItems.Add(motionItemLineStart);
                motionItemLineStart.dEndU = StartTransfer.U;
            }
            if (空动作路径 == false)
            {
                MotionItemOutput motionItemOutput = new MotionItemOutput();
                motionItemOutput.On = true;
                motionItems.Add(motionItemOutput);
            }

            if (this.开胶后延时时间 > 0)
            {
                MotionItemDelay motionItemDelay = new MotionItemDelay();
                motionItemDelay.dDelayTime = this.开胶后延时时间;
                motionItems.Add(motionItemDelay);
            }

            

            MotionItemCircle motionItemCircle = new MotionItemCircle(spdXYGlue, StartTransfer,CenterTransfer, 圆的角度);
            
           
            motionItems.Add(motionItemCircle);
            
           motionItemCircle.dEndU = StartTransfer.U+ 圆的角度;
            
            if (bIsContinueWithAferAndAfterIsOnGlue == false)
            {
                MotionItemOutput motionItemOutput = new MotionItemOutput();
                motionItemOutput.On = false;
               
                motionItemCircle.dEndU = StartTransfer.U + 圆的角度;
               
                motionItems.Add(motionItemOutput);
            }
            if (bContinueWithAferItem == false)
            {
                PointData pointDataNew = new PointData(StartTransfer);
                
                pointDataNew.U = StartTransfer.U + 圆的角度;

                MotionItemLine motionItemLineUp = new MotionItemLine(spdZH, pointDataNew);
                motionItemLineUp.Point.Z = gluePathUnit.全局安全高度Z;

                motionItemCircle.dEndU = StartTransfer.U + 圆的角度;

                motionItems.Add(motionItemLineUp);
            }
            #endregion
        }

        private void TranferPosToCur(GluePathUnit gluePathUnit,bool bContinueWithBeforeItem, List<MotionItemBase> motionItems,double dOffsetZ)
        {
            if (FrameManager.MachineStatus.Is4Axis == false)
                圆的角度 =0;
            if (Math.Abs(圆的角度) > 0)
            {
                //圆的角度 = -360.0;
                PointData Pos1 = new PointData(Start);
                PointData Pos2 = new PointData(Start);
                PointData Pos3 = new PointData(Start);
                double dR = Math.Sqrt((Start.Y - Center.Y) * (Start.Y - Center.Y) + (Start.X - Center.X) * (Start.X - Center.X));
                double dStartAnglePi = Math.Atan2(Start.Y - Center.Y, Start.X - Center.X);
                double dStartAngle = 180 * dStartAnglePi / Math.PI;
                double dStartAngle2 = dStartAngle + 120;
                double dStartAngle3 = dStartAngle + 240;
                double dStartAngle2Pi = (dStartAngle + 120) * Math.PI / 180.0;
                double dStartAngle3Pi = (dStartAngle + 240) * Math.PI / 180.0; ;
                Pos2.X = Center.X + R * Math.Cos(dStartAngle2Pi);
                Pos2.Y = Center.Y + R * Math.Sin(dStartAngle2Pi);
                Pos3.X = Center.X + R * Math.Cos(dStartAngle3Pi);
                Pos3.Y = Center.Y + R * Math.Sin(dStartAngle3Pi);

                double dNewCenterX, dNewCenterY, dNewR;


                PointData CenterTemp = new PointData(Center);
                if (bContinueWithBeforeItem)
                {
                    Pos1.U = motionItems[motionItems.Count - 1].dEndU;
                    Pos2.U = motionItems[motionItems.Count - 1].dEndU + Math.Abs(圆的角度 / 3);
                    Pos3.U = motionItems[motionItems.Count - 1].dEndU + Math.Abs(圆的角度 * 2 / 3);
                }
                else
                {
                    Pos1.U = Start.U;
                    Pos2.U = Start.U - 圆的角度 / 3;
                    Pos3.U = Start.U - 圆的角度 * 2 / 3;
                    CenterTemp.U = Center.U;
                }

                PointData pointDataLocalStart = WhereAtLocal(Pos1, gluePathUnit.StandardLocalX, gluePathUnit.StandardLocalY, gluePathUnit.StandardLocalU);
                StartTransfer = TranLocalToMotor(pointDataLocalStart, gluePathUnit.CurrentLocalX, gluePathUnit.CurrentLocalY, gluePathUnit.CurrentLocalU);
                AddToolOffSet(gluePathUnit, StartTransfer);

                PointData pointDataLocalMid = WhereAtLocal(Pos2, gluePathUnit.StandardLocalX, gluePathUnit.StandardLocalY, gluePathUnit.StandardLocalU);
                PointData MidTransfer = TranLocalToMotor(pointDataLocalMid, gluePathUnit.CurrentLocalX, gluePathUnit.CurrentLocalY, gluePathUnit.CurrentLocalU);
                AddToolOffSet(gluePathUnit, MidTransfer);

                PointData pointDataLocalEnd = WhereAtLocal(Pos3, gluePathUnit.StandardLocalX, gluePathUnit.StandardLocalY, gluePathUnit.StandardLocalU);
                PointData EndTransfer = TranLocalToMotor(pointDataLocalEnd, gluePathUnit.CurrentLocalX, gluePathUnit.CurrentLocalY, gluePathUnit.CurrentLocalU);
                AddToolOffSet(gluePathUnit, EndTransfer);

                GetCircle(StartTransfer.X, StartTransfer.Y, MidTransfer.X, MidTransfer.Y, EndTransfer.X, EndTransfer.Y, out dNewCenterX, out dNewCenterY, out dNewR);

                CenterTransfer = new PointData(Center);
                CenterTransfer.X = dNewCenterX;
                CenterTransfer.Y = dNewCenterY;
                RTransfer = dNewR;
            }
            else
            {
                圆的角度 = 0;
                PointData pointDataLocalStart = WhereAtLocal(Start, gluePathUnit.StandardLocalX, gluePathUnit.StandardLocalY, gluePathUnit.StandardLocalU);
                StartTransfer = TranLocalToMotor(pointDataLocalStart, gluePathUnit.CurrentLocalX, gluePathUnit.CurrentLocalY, gluePathUnit.CurrentLocalU);
                AddToolOffSet(gluePathUnit, StartTransfer);

                PointData pointDataLocalCenter = WhereAtLocal(Center, gluePathUnit.StandardLocalX, gluePathUnit.StandardLocalY, gluePathUnit.StandardLocalU);
                CenterTransfer = TranLocalToMotor(pointDataLocalCenter, gluePathUnit.CurrentLocalX, gluePathUnit.CurrentLocalY, gluePathUnit.CurrentLocalU);
                AddToolOffSet(gluePathUnit, CenterTransfer);
                RTransfer = R;
            }
            StartTransfer.Z = StartTransfer.Z-dOffsetZ;
            CenterTransfer.Z = CenterTransfer.Z - dOffsetZ;




            //PointData pointDataLocalCenter = WhereAtLocal(Center, gluePathUnit.StandardLocalX, gluePathUnit.StandardLocalY, gluePathUnit.StandardLocalU);
            //CenterTransfer = TranLocalToMotor(pointDataLocalCenter, gluePathUnit.CurrentLocalX, gluePathUnit.CurrentLocalY, gluePathUnit.CurrentLocalU);
            //AddToolOffSet(gluePathUnit, CenterTransfer);
        }
        public bool GetCircle(double dX1, double dY1, double dX2, double dY2, double dX3, double dY3,
          out double dCenterX, out double dCenterY, out double dR)
        {
            dCenterX = 0.0;
            dCenterY = 0.0;
            dR = 0.0;
            double dA1, dB1, dA2, dB2;
            double dCrossX = 0.0;
            double dCrossY = 0.0;
            //Line1
            bool bLine1Ok = GetLine(dX1, dY1, dX2, dY2, out dA1, out dB1);

            //Line1
            bool bLine2Ok = GetLine(dX2, dY2, dX3, dY3, out dA2, out dB2);
            //Cross

            if (bLine1Ok && bLine2Ok)
            {
                LineCross(dA1, dB1, dA2, dB2, out dCrossX, out dCrossY);
            }
            else
            {
                if (bLine1Ok == false && bLine2Ok == false)
                {
                    return false;
                }
                if (bLine1Ok == false)
                {
                    dCrossX = dB1;
                    dCenterY = dCrossX * dA2 + dB2;
                }
                if (bLine2Ok == false)
                {
                    dCrossX = dB2;
                    dCenterY = dCrossX * dA1 + dB1;
                }
            }
            dCenterX = dCrossX;
            dCenterY = dCrossY;
            dR = Math.Sqrt((dX1 - dCrossX) * (dX1 - dCrossX) + (dY1 - dCrossY) * (dY1 - dCrossY));
            return true;
        }
        private bool GetLine(double dX1, double dY1, double dX2, double dY2, out double dA, out double dB)
        {
            dA = 0.0;
            dB = 0.0;
            double dTempA, dTempB;
            double dX, dY;
            if (Math.Abs(dX1 - dX2) < 0.00000001)
            {
                dA = 0.0;
                dB = (dY1 + dY2) / 2.0;
                return true;
            }
            if (Math.Abs(dY1 - dY2) < 0.00000001)
            {
                dA = 0.0;
                dB = (dX1 + dX2) / 2.0;
                return false;
            }
            dTempA = (dY2 - dY1) / (dX2 - dX1);
            dTempB = dY1 - dA * dX1;
            //计算直线中点
            dX = (dX1 + dX2) / 2.0;
            dY = (dY1 + dY2) / 2.0;
            //中垂线
            dA = -1 / dTempA;
            dB = dY - dA * dX;
            return true;

        }
        private void LineCross(double dA1, double dB1, double dA2, double dB2, out double dCrossX, out double dCrossY)
        {
            dCrossX = 0.0;
            dCrossY = 0.0;
            dCrossX = (dB1 - dB2) / (dA2 - dA1);
            dCrossY = dA1 * dCrossX + dB1;
        }
        //public bool IsCW()
        //{
        //    if (圆的角度 > 0)
        //    {
        //        return true;

        //    }
        //    else
        //    {
        //        return false;
        //    }
        //}
    }
}
